import React from 'react';

export interface ISpinBoxProps {
  onChange?: (value: number) => void;
  minValue?: number;
  maxValue?: number;
  step?: number;
  editable: boolean;
  disabled?: boolean;
  defaultValue?: number;
  type?: string;
}

export default class SpinBox extends React.Component<ISpinBoxProps, any> {

  constructor(props: ISpinBoxProps) {
    super(props);
    this.state = {
      value: this.props.defaultValue === undefined ? 1 : this.props.defaultValue,
      step: this.props.step === undefined ? 1 : this.props.step,
    };
    this.onChange = this.onChange.bind(this);
    this.handleAddClick = this.handleAddClick.bind(this);
    this.handleSubClick = this.handleSubClick.bind(this);
  }

  public onChange(event: any) {
    let result;
    let maxValue = this.props.maxValue;
    let minValue = this.props.minValue;
    let value: string = event.target.value.replace(/[^\d]/g, '');
    if (value === '' || value === null) {
      value = '0';
    }
    if (minValue === undefined && maxValue === undefined) {
      result = parseInt(value, undefined);
    } else if (minValue !== undefined && maxValue === undefined) {
      if (parseInt(value, undefined) <= minValue) {
        result = minValue;
      } else {
        result = parseInt(value, undefined);
      }
    } else if (minValue === undefined && maxValue !== undefined) {
      if (parseInt(value, undefined) >= maxValue) {
        result = maxValue;
      } else {
        result = parseInt(value, undefined);
      }
    } else if (minValue !== undefined && maxValue !== undefined) {
      if (parseInt(value, undefined) >= maxValue) {
        result = maxValue;
      } else if (parseInt(value, undefined) <= minValue) {
        result = minValue;
      } else {
        result = parseInt(value, undefined);
      }
    } else {
      result = parseInt(value, undefined);
    }
    if (this.props.onChange !== undefined) {
      this.props.onChange(result);
    }
    this.setState({
      value: result,
    });
  }

  public handleAddClick(event: any) {
    if (this.props.disabled) {
      return;
    }
    let result;
    let maxValue = this.props.maxValue;
    let addResult = this.state.value + this.state.step;
    if (maxValue === undefined) {
      result = addResult;
    } else if (addResult > maxValue) {
      result = maxValue;
    } else {
      result = addResult;
    }
    if (this.props.onChange !== undefined) {
      this.props.onChange(result);
    }
    this.setState({
      value: result,
    });
  }

  public handleSubClick(event: any) {
    if (this.props.disabled) {
      return;
    }
    let result;
    let minValue = this.props.minValue;
    let subResult = this.state.value - this.state.step;
    if (minValue === undefined) {
      result = subResult;
    } else if (subResult < minValue) {
      result = minValue;
    } else {
      result = subResult;
    }
    if (this.props.onChange !== undefined) {
      this.props.onChange(result);
    }
    this.setState({
      value: result,
    });
  }

  public render() {
    let classSubString = '';
    let classAddString = '';
    let classInputString = '';
    const className = this.props.type;
    if (this.props.type) {
      classSubString = `spin-box-sub-${className}`;
      classAddString = `spin-box-add-${className}`;
      classInputString = `spin-box-input-${className}`;
      return (
        <div className="user-select">
          <span className={classSubString} onClick={this.handleSubClick}>
            <i className="icon icon-subtract small-font-big"></i>
          </span>
          <input
            readOnly={!this.props.editable}
            disabled={this.props.disabled}
            className={classInputString}
            onChange={this.onChange}
            value={this.state.value}
            type="text"
          />
          <span className={classAddString} onClick={this.handleAddClick}>
            <i className="icon icon-add small-font-big"></i>
          </span>
        </div>
      );
    } else {
      classSubString = `spin-box-sub-small`;
      classAddString = `spin-box-add-small`;
      classInputString = `spin-box-input-small`;
      return (
        <div className="user-select">
          <span className={classSubString} onClick={this.handleSubClick}>
            <i className="icon icon-subtract small-font"></i>
          </span>
          <input
            readOnly={!this.props.editable}
            disabled={this.props.disabled}
            className={classInputString}
            onChange={this.onChange}
            value={this.state.value}
            type="text"
          />
          <span className={classAddString} onClick={this.handleAddClick}>
            <i className="icon icon-add small-font"></i>
          </span>
        </div>
      );
    }
  }
}
